﻿// -----------------------------------------------------------------------
// <copyright file="DeflateDecompressor.cs">
// Copyright (c) 2013 Andrey Veselov. All rights reserved.
// License:  Microsoft Public License (MS-PL)
// Contacts: http://andrey.moveax.com  andrey@moveax.com
// </copyright>
// -----------------------------------------------------------------------

namespace PortableImagingLibrary.Png.Compressors
{
    using System;
    using System.IO;
    using Ionic.Zlib;

    internal class DeflateCompressor : ICompressor
    {
        // ReSharper disable RedundantDefaultFieldInitializer
        private bool _disposed = false;
        // ReSharper restore RedundantDefaultFieldInitializer

        private readonly MemoryStream _memoryStream;
        private readonly ZlibStream _zlibStream;

        public DeflateCompressor()
        {
            this._memoryStream = new MemoryStream();
            this._zlibStream = new ZlibStream(this._memoryStream, CompressionMode.Compress, CompressionLevel.BestCompression) {
                FlushMode = FlushType.Sync
            };
        }

        ~DeflateCompressor()
        {
            this.Dispose(false);
        }

        #region ICompressor Members

        public void AddLine(byte[] source)
        {
            if (this._disposed)
                throw new ObjectDisposedException("DeflateCompressor");

            this._zlibStream.Write(source, 0, source.Length);
        }

        public byte[] GetChunkData()
        {
            if (this._disposed)
                throw new ObjectDisposedException("DeflateCompressor");

            var data = this._memoryStream.ToArray();
            return data;
        }

        #endregion ICompressor Members

        #region IDisposable Members

        public void Dispose()
        {
            this.Dispose(true);

            GC.SuppressFinalize(this);
        }

        #endregion IDisposable Members

        private void Dispose(bool disposing)
        {
            if (this._disposed && !disposing)
                return;

            this._zlibStream.Dispose();
            this._memoryStream.Dispose();
            this._disposed = true;
        }
    }
}
